﻿using Common.Communication;
using Common.Tool.DataTools;
using DeviceBase;
using DeviceBase.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Remoting.Channels;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace DianYuan.Core.Unit
{
    public class UDP3305S_ENiVisa : NiVisaBase, IDianYuan, IDevice
    {
        public string Name { get; set; }
        public UDP3305S_ENiVisa(string name, string sn, int timeout = 1500) : base(sn, timeout)
        {
            Name = name;
        }
        public Result<bool> SetOn(double vol, double cur = 0, int channel = 1)
        {
            string command = "";
            Result<bool> result = new Result<bool>();
            AppendInfo(Name, $"通道{channel}设置输出{vol}V,{cur}A");
            command = CmdApply(channel, vol, cur);
            var re = Write(command);
            if (!re.IsSucceed)
            {
                result.IsSucceed = false;
                result.Err = "设置输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            Thread.Sleep(100);
            command = CmdGetApply(channel);
            //发送指令并返回
            var re2 = WriteThenRead(command);
            if (!re2.IsSucceed || re2.Value.Count(o => o == ',') != 2)
            {
                result.IsSucceed = false;
                result.Err = "设置输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            string[] value = re2.Value.Split(',');
            if (value.Length != 3)
            {
                result.IsSucceed = false;
                result.Err = "设置输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            float V = float.Parse(value[1]);
            float A = float.Parse(value[2]);
            if (V != vol || A != cur)
            {
                result.IsSucceed = false;
                result.Err = "设置输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            AppendInfo(Name, $"通道{channel}打开输出");
            command = CmdOutPutOn(channel);
            re = Write(command);
            if (!re.IsSucceed)
            {
                result.IsSucceed = false;
                result.Err = "打开输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            Thread.Sleep(100);
            command = CmdGetOutPut(channel);
            //发送指令并返回
            re2 = WriteThenRead(command);
            if (!re2.IsSucceed || !re2.Value.Contains(CmdOn))
            {
                result.IsSucceed = false;
                result.Err = "打开输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            AppendInfo(Name, "设置输出成功");
            return result.EndTime();
        }
        public Result<bool> SetOff(int channel = 1)
        {
            string command = "";
            Result<bool> result = new Result<bool>();
            AppendInfo(Name, $"通道{channel}关闭输出");
            command = CmdOutPutOff(channel);
            var re = Write(command);
            if (!re.IsSucceed)
            {
                result.IsSucceed = false;
                result.Err = "关闭输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            Thread.Sleep(100);
            command = CmdGetOutPut(channel);
            //发送指令并返回
            var re2 = WriteThenRead(command);
            if (!re2.IsSucceed || !re2.Value.Contains(CmdOff))
            {
                result.IsSucceed = false;
                result.Err = "关闭输出失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            AppendInfo(Name, "关闭输出成功");
            return result.EndTime();
        }
        public Result<double> GetVoltage(int channel = 1)
        {
            string command = "";
            double vol = 0f;
            Result<double> result = new Result<double>();
            AppendInfo(Name, $"通道{channel}读取当前电压");
            command = CmdGetVolt(channel);
            //发送指令并返回
            var re2 = WriteThenRead(command);
            if (!re2.IsSucceed || !double.TryParse(re2.Value, out vol))
            {
                result.IsSucceed = false;
                result.Err = "读取当前电压失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            result.Value = vol;
            AppendResult(Name, DataConvert.ToUnit(vol, "F3") + "V");
            return result.EndTime();
        }
        public Result<double> GetCurrent(int channel = 1)
        {
            string command = "";
            double cur = 0f;
            Result<double> result = new Result<double>();
            AppendInfo(Name, $"通道{channel}读取当前电流");
            command = CmdGetCurr(channel);
            //发送指令并返回
            var re2 = WriteThenRead(command);
            if (!re2.IsSucceed || !double.TryParse(re2.Value, out cur))
            {
                result.IsSucceed = false;
                result.Err = "读取当前电流失败";
                AppendResult(Name, result.Err);
                return result.EndTime();
            }
            result.Value = cur;
            AppendResult(Name, DataConvert.ToUnit(cur,"F3") + "A");
            return result.EndTime();
        }
        string CmdApply(int channel, double vol, double cur) => $"APPL CH{channel},{vol.ToString("F2")}V,{cur.ToString("F3")}A\r\n";
        string CmdGetApply(int channel) => $"APPLy? CH{channel}\r\n";
        string CmdOutPutOn(int channel) => $"OUTPut:STATe CH{channel}, ON\r\n";
        string CmdOutPutOff(int channel) => $"OUTPut:STATe CH{channel}, OFF\r\n";
        string CmdGetOutPut(int channel) => $"OUTPut:STATe? CH{channel}\r\n";
        string CmdOn => "ON";
        string CmdOff => "OFF";
        string CmdGetVolt(int channel) => $"MEAS:VOLT? CH{channel}\r\n";
        string CmdGetCurr(int channel) => $"MEAS:CURR? CH{channel}\r\n";
    }
}
